from rest_framework import serializers
from .models import Order, OrderDetail
from course.models import Course
from rest_framework.exceptions import APIException
import uuid
from libs.alipay_common import alipay, gateway

from django.conf import settings


# 校验，保存
class PaySerializer(serializers.ModelSerializer):
    # 高级用法 传入的courses=[1,2,3]---->courses=[id为1的课程对象,id为2的课程对象,id为3的课程对象]
    courses = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(), many=True)

    class Meta:
        model = Order
        fields = ['subject', 'total_amount', 'pay_type', 'courses']

    def _check_price(self, attrs):
        # 取出前端传入的总价格
        total_amount = attrs.get('total_amount')
        # 根据传入的课程，计算出总价格，做比较
        courses = attrs.get('courses')  # 是一个个对象了
        real_total_amount = 0
        for course in courses:
            real_total_amount += course.price
        if not total_amount == real_total_amount:
            raise APIException('价格不一致')

    def _get_order_no(self):
        return str(uuid.uuid4())

    def _get_user(self):
        # 返回当前登录用户
        request = self.context.get('request')
        return request.user

    def _get_pay_url(self, order_no, subject, total_amount):
        res = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_no,
            total_amount=float(total_amount),
            subject=subject,
            return_url=settings.RETURN_URL,  # get回调地址，支付宝前端回调的
            notify_url=settings.NOTIFY_URL  # post回调地址，支付宝会向这个接口发送post请求，告诉俺们支付成功了
        )
        pay_url = gateway + res
        return pay_url

    def validate(self, attrs):
        # 1）订单总价校验
        self._check_price(attrs)
        # 2）生成订单号：唯一的
        out_trade_no = self._get_order_no()
        # 3）获取支付用户：request.user
        user = self._get_user()
        # 4）支付链接生成：支付宝支付链接
        pay_url = self._get_pay_url(out_trade_no, attrs.get('subject'), attrs.get('total_amount'))
        # 5）入库(两个表)的信息准备
        attrs['user'] = user
        attrs['out_trade_no'] = out_trade_no
        # attrs={'subject', 'total_amount', 'pay_type', 'courses',user,order_no}
        self.context['pay_url'] = pay_url
        return attrs

    def create(self, validated_data):  # {'subject', 'total_amount', 'pay_type', 'courses',user,order_no}
        courses = validated_data.pop('courses')
        order = Order.objects.create(**validated_data)
        for course in courses:
            OrderDetail.objects.create(order=order, course=course, price=course.price, real_price=course.price)

        return order
